package com.yx.cloud.product.gyro;

import android.content.Context;
import android.content.res.Resources;
import android.util.Base64;

import com.google.gson.Gson;
import com.iot.base.bean.Device;
import com.iot.base.service.req.DataBag;
import com.iot.base.service.req.DataParam;
import com.iot.common.utils.Event;
import com.iot.common.utils.LogUtils;
import com.iot.common.utils.StringUtils;
import com.iot.common.utils.ZipUtil;
import com.iot.product.sweeper.bean.Appointment;
import com.iot.product.sweeper.bean.CleanRecord;
import com.iot.product.sweeper.bean.FirmwareUpdateInfo;
import com.iot.product.sweeper.bean.Path;
import com.iot.product.sweeper.bean.CleanParam;
import com.iot.product.sweeper.bean.Robot;
import com.iot.product.sweeper.bean.RobotStatus;
import com.iot.sdk.yugong.YuGongConstants;
import com.iot.sdk.yugong.YuGongError;
import com.iot.sdk.yugong.YuGongResponse;
import com.iot.sdk.yugong.YuGongSdk;
import com.iot.sdk.yugong.req.YuGongChannelReqBreakContinue;
import com.iot.sdk.yugong.req.YuGongChannelReqLight;
import com.iot.sdk.yugong.req.YuGongChannelReqLocateDevice;
import com.iot.sdk.yugong.req.YuGongChannelReqRemoteControl;
import com.iot.sdk.yugong.req.YuGongChannelReqSuction;
import com.iot.sdk.yugong.req.YuGongChannelReqWorkingStatus;
import com.iot.sdk.yugong.req.YuGongGetAppointmentList;
import com.iot.sdk.yugong.req.YuGongGyroAddAppointment;
import com.iot.sdk.yugong.req.YuGongGyroModifyAppointment;
import com.iot.sdk.yugong.req.YuGongPayloadAddNoDisturb;
import com.iot.sdk.yugong.req.YuGongPayloadData;
import com.iot.sdk.yugong.req.YuGongPayloadDataList;
import com.iot.sdk.yugong.req.YuGongPayloadDeleteAppointment;
import com.iot.sdk.yugong.req.YuGongPayloadGyroSendMcuUpgradeUrl;
import com.iot.sdk.yugong.req.YuGongPayloadGyroSendWifiUpgradeUrl;
import com.iot.sdk.yugong.req.YuGongPayloadModifyNoDisturb;
import com.iot.sdk.yugong.req.YuGongPayloadSendVoiceBagUrl;
import com.iot.sdk.yugong.req.YuGongPayloadSwitchAppointment;
import com.iot.sdk.yugong.resp.YuGongRespData;
import com.iot.sdk.yugong.resp.YuGongRespDataCommon;
import com.iot.sdk.yugong.resp.YuGongRespDataGetAppointment;
import com.iot.sdk.yugong.resp.YuGongRespDataList;
import com.iot.sweeper.param.AddAppointmentParam;
import com.iot.sweeper.param.ChangeAppointmentParam;
import com.iot.sweeper.param.CleanSettingParam;
import com.iot.sweeper.param.DeleteAppointmentParam;
import com.iot.sweeper.param.GetCleanRecordDetailParam;
import com.iot.sweeper.param.GetCleanRecordParam;
import com.iot.sweeper.param.RemoteControlParam;
import com.iot.sweeper.param.RemoveMultiMapList;
import com.iot.sweeper.param.ResetComsuptionParam;
import com.iot.sweeper.param.SetQuiteTimeParam;
import com.iot.sweeper.product.YuGongDataConverter;
import com.iot.sweeper.product.YuGongDefaultSweeperProduct;
import com.yx.cloud.AppStatusConstant;
import com.yx.cloud.MyApplication;
import com.yx.cloud.R;
import com.yx.cloud.product.ProductConfigConstants;
import com.yx.cloud.product.gyro.bean.GyroMapInfo;
import com.yx.cloud.product.laser.tuyapublic.ParseResult;
import com.yx.cloud.product.laser.yxcloud.YxCloudLaserDataConverter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import retrofit2.Call;
import retrofit2.Callback;

public class N5 extends YuGongDefaultSweeperProduct {
    public static final String PID = "n5-full";
    public static final String PNAME = "N5";
    private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>(50));
    private Gson gson = new Gson();
    private Robot currentDevice;

    protected N5() {
        getMap().setMap(new GyroMapInfo());
        getMap().setPath(new Path());
        setProductId(PID);
        getProduct().setProductName(PNAME);
        getProduct().setProductIcon(R.mipmap.robot_icon_pic_n5);
    }

    @Override
    public void setDeviceId(String deviceId) {
        super.setDeviceId(deviceId);
        try {
            //因为机器设置的风格图片是通过deviceid做key的  在创建对象初始化配置时还没有设置deviceid 所以在这里设置
//            product.getConfigureMap().put(ProductConfigConstants.robot_Airview, N5Config.getRobotAirview(deviceId));
            product.getConfigureMap().put(ProductConfigConstants.robot_Airview, R.mipmap.main_n5_icon);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void parseDeviceData(Device device, Object data) {
        currentDevice = (Robot) device;
        try {
            LogUtils.i("N5 receive channel data:" + data);
            JSONObject dataJson;
            dataJson = new JSONObject((String) data);
//            if (!dataJson.has(YuGongConstants.NOTIFY_INFO)) {
//                if (!dataJson.has("func")) {//语言设置结果返回
//                    return;
//                } else {
//                    Event.newBuilder().type(Event.MESSAGE_TYPE_DATA_FUNC).result(true).content(data).send();
//                    return;
//                }
//            }
            String type = dataJson.getString(YuGongConstants.NOTIFY_INFO);

            //{"notify_info": "map_data", "map_data": "eNqrVirPTCnJULIy0VHKyEzPKFGyMtRRyk0siM8vykzPzFOyijY0stAB4lgdpaL8pPyS+IL8YhTR5JzUxLz4kszc1HighAFEd0piSaKSlZKjo62tUi0ARH8fHA==", "thing_name": "n5-full-G1-8b-22-77-c3-36"}
            if (type.equals(YuGongConstants.NOTIFY_TYPE_MAP)) {
                if (coundownIgnoreMapCount()) {
                    LogUtils.i("abandon map data : " + ignoreMapCount);
                    return;
                }
                String mapData = dataJson.getString(YuGongConstants.NOTIFY_TYPE_MAP);

                if (mapData == null) {
                    return;
                }

                byte[] compressed = Base64.decode(mapData, Base64.DEFAULT);//base64解密]
                if (compressed == null || compressed.length == 0) {
                    LogUtils.i("map data is null");
                    return;
                }
                byte[] bytes = ZipUtil.decompress(compressed);//zip解压
                ParseResult mapResult = GyroMapDataParser.parseMapData(getMap(), bytes);

                LogUtils.i("YxCloud map result is" + mapResult.getCode());
                if (mapResult.getCode() != ParseResult.MSG_PARSE_SUCCESS) {
                    LogUtils.i("YxCloud  map clear" + mapResult.getCode());
                    getMap().getRoom().clear();
                    getMap().getArea().clear();
                    getMap().getPath().clear();
                    getMap().getSweeper().clear();
                    getMap().getPower().clear();
                    getMap().getMap().mapData = null;

                }
                GyroMapInfo mapInfo = (GyroMapInfo) getMap().getMap();
                LogUtils.i("YxCloud  map cleanTime cleanArea : " + mapInfo.cleanArea + ", " + mapInfo.cleanTime);
                currentDevice.getCleanStatistics().setCleanArea(mapInfo.cleanArea);
                currentDevice.getCleanStatistics().setCleanTime(mapInfo.cleanTime);
                Event.newBuilder().type(Event.MESSAGE_TYPE_CLEAN_AREA_DURATION).result(true).send();
                Event.newBuilder().type(Event.MSG_ROBOT_MAP).result(true).content(getMap().getMap()).send();
            } else if (type.equals(YuGongConstants.NOTIFY_TYPE_STATUS)) {
                parseDp(dataJson);
            } else if (type.equals(YuGongConstants.NOTIFY_TYPE_DEVICE_RESET)) {
                //设备重置
                LogUtils.i("重置 广播了。。。。。" + MyApplication.recvActive);
                boolean factory_reset = dataJson.getBoolean("factory_reset");
                if (!MyApplication.recvActive) {
                    Event.newBuilder().type(Event.MESSAGE_TYPE_DEVICE_RESET_LIST).result(true).content(factory_reset).send();
                } else {
                    Event.newBuilder().type(Event.MESSAGE_TYPE_DEVICE_RESET).result(true).content(factory_reset).send();
                }
            } else if (type.equals(YuGongConstants.NOTIFY_TYPE_UPGRADE_RESULT)) {
                //固件升级结果 upgrade_result
                String result = dataJson.getString("upgrade_result");
                LogUtils.i("N5 固件 固件升级结果 :" + result);
                Event.newBuilder().type(Event.MESSAGE_TYPE_UPGRADE_RESULT).result(true).content(result).send();
            } else {
                //TODO 其他数据类型的解析
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void parseDp(JSONObject dataJson) throws JSONException {
        if (coundownIgnoreStateCount()) {
            LogUtils.i("n5 abandon state data : " + ignoreStateCount);
            return;
        }

        JSONObject statusJson = dataJson.getJSONObject("thing_status");
        YxCloudLaserDataConverter.parseDp(this, statusJson);
        initRobotData(this, statusJson);
    }

    @Override
    public void initConfig() {
        super.initConfig();
        //TODO 后续考虑从文件中读取
        N5Config.initConfig(getProduct().getConfigureMap(), this);
    }

    private void initRobotData(Robot robot, JSONObject jsonObject) {
        LogUtils.i("n5 initRobotData : " + new Gson().toJson(jsonObject));
        try {
            if (jsonObject.has(GyroLaserConstant.WORKING_STATUS)) {
                String robot_state = jsonObject.getString(GyroLaserConstant.WORKING_STATUS);
                parseState(robot_state, robot);
            }
            if (jsonObject.has(GyroLaserConstant.BATTERY_LEVEL)) {
                //电量
                int battery = jsonObject.getInt(GyroLaserConstant.BATTERY_LEVEL);
                robot.getRobotStatus().setBattery(battery);
                Event.newBuilder().type(Event.MSG_ROBOT_STATE_POWER).content(battery).send();
                //低电量
                if (battery < 20) {
                    Event.newBuilder().type(Event.MSG_ROBOT_STATE_LOW_POWER).content(battery).send();
                } else {
                    Event.newBuilder().type(Event.MSG_ROBOT_STATE_HEALTH_POWER).content(battery).send();
                }
            }
            if (jsonObject.has(GyroLaserConstant.FAN_STATUS)) {
                //吸力 closed - 关闭 gentle - 安静 normal - 正常 strong - 强劲 max - 超强
                String suction = jsonObject.getString(GyroLaserConstant.FAN_STATUS);
                int mSuction = 0;
                if ("None".equals(suction)) {
                    //未安装尘盒，不可控
                    mSuction = 0;
                } else if ("Quiet".equals(suction)) {
                    //安静 1档
                    mSuction = 1;
                } else if ("Normal".equals(suction)) {
                    //正常 2档
                    mSuction = 2;
                } else if ("Strong".equals(suction)) {
                    //强力 3档
                    mSuction = 3;
                } else if ("Max".equals(suction)) {
                    //最大
                    mSuction = 4;
                }
                robot.getCleanSettings().setSuction(mSuction);
                Event.newBuilder().result(true).type(Event.MESSAGE_TYPE_SUCTION_STATUS).content(suction).send();
            }
            if (jsonObject.has(GyroLaserConstant.WATER_LEVEL)) {
                //水量 closed - 关闭 low - 低 middle - 中 high - 高
                String water_mode = jsonObject.getString(GyroLaserConstant.WATER_LEVEL);
                int mWater_mode = 0;
                if ("None".equals(water_mode)) {
                    //未安装尘盒，不可控
                    mWater_mode = 0;
                } else if ("Low".equals(water_mode)) {
                    //安静 1档
                    mWater_mode = 1;
                } else if ("Default".equals(water_mode)) {
                    //正常 2档
                    mWater_mode = 2;
                } else if ("High".equals(water_mode)) {
                    //强力 3档
                    mWater_mode = 3;
                } else if ("Max".equals(water_mode)) {
                    //最大
                    mWater_mode = 4;
                }
                robot.getCleanSettings().setMopHumidity(mWater_mode);
                Event.newBuilder().result(true).type(Event.MESSAGE_TYPE_WATER_STATUS).content(water_mode).send();
            }
            if (jsonObject.has(GyroLaserConstant.ERROR_CODE)) {
                int fault = jsonObject.getInt(GyroLaserConstant.ERROR_CODE);
                //如果是错误状态 显示异常的条条， 如果不是 隐藏它
                robot.getRobotStatus().setError(fault + "");
                Event.newBuilder().type(Event.MESSAGE_TYPE_FAULT_STATUS).result(true).send();
            }

            if (jsonObject.has(GyroLaserConstant.SIDE_BRUSH)) {
                //边刷寿命
                String edge_brush = jsonObject.getString(GyroLaserConstant.SIDE_BRUSH);
                JSONObject json_brush = new JSONObject(edge_brush);
                int left_hour = json_brush.getInt("left_hour") * 3600;
                int used_hour = json_brush.getInt("used_hour") * 3600;
                LogUtils.i("边刷寿命 left_hour:" + left_hour + " , used_hour: " + used_hour);
                robot.getConsumption().setSideBrushLife(left_hour);
                Event.newBuilder().result(true).type(Event.MESSAGE_TYPE_CONSUMPTION_UPDATE).content("N5").send();
            }
            if (jsonObject.has(GyroLaserConstant.FILTER)) {
                //滤网寿命
                String strainerLife = jsonObject.getString(GyroLaserConstant.FILTER);
                JSONObject json_filter = new JSONObject(strainerLife);
                int left_hour = json_filter.getInt("left_hour") * 3600;
                int used_hour = json_filter.getInt("used_hour") * 3600;
                LogUtils.i("滤网寿命 left_hour:" + left_hour + " , used_hour: " + used_hour);
                robot.getConsumption().setStrainerLife(left_hour);
                Event.newBuilder().result(true).type(Event.MESSAGE_TYPE_CONSUMPTION_UPDATE).content("N5").send();
            }
            if (jsonObject.has(GyroLaserConstant.CONTINUE_CLEAN)) {
                //断点续扫
                boolean breakpoint = jsonObject.getBoolean(GyroLaserConstant.CONTINUE_CLEAN);
                robot.getCleanSettings().setBreakpointResume(breakpoint);
                Event.newBuilder().type(Event.MESSAGE_TYPE_BREAKPOINT_RESUME_SWITCH).result(true).send();
            }
            if (jsonObject.has(GyroLaserConstant.LIGHT_ON)) {
                //灯光
                boolean lightOn = jsonObject.getBoolean(GyroLaserConstant.LIGHT_ON);
                robot.getCleanSettings().setLightSwitch(lightOn);
            }
            if (jsonObject.has(GyroLaserConstant.UPGRADE_STATUS)) {
                //升级状态
                String upgrade_status = jsonObject.getString(GyroLaserConstant.UPGRADE_STATUS);
                if ("upgrading_download_device".equals(upgrade_status)) {
                    //下载wifi固件
                    robot.getFirmwareUpdateInfo().setState(1);
                } else if ("upgrading_download_chassis".equals(upgrade_status)) {
                    //下载底盘固件
                    robot.getFirmwareUpdateInfo().setState(2);
                } else if ("upgrading_install_chassis".equals(upgrade_status)) {
                    //安装底盘固件
                    robot.getFirmwareUpdateInfo().setState(3);
                } else if ("idle".equals(upgrade_status)) {
                    //未在升级状态
                    robot.getFirmwareUpdateInfo().setState(0);
                }
                LogUtils.i("固件 升级状态=====" + upgrade_status);
            }
            if (jsonObject.has(GyroLaserConstant.UPGRADE_PROGRESS)) {
                //升级进度
                int upgrade_progress = jsonObject.getInt(GyroLaserConstant.UPGRADE_PROGRESS);
                if (upgrade_progress > 0) {
                    robot.getFirmwareUpdateInfo().setProgress(upgrade_progress);
                    LogUtils.i("固件 升级进度=====" + upgrade_progress);
                    Event.newBuilder().type(Event.MESSAGE_TYPE_GYRO_UPGRADE_PROGRESS).result(true).content(upgrade_progress).send();
                }
            }
            if (jsonObject.has(GyroLaserConstant.YUGONG_SOFTWARE_VERSION)) {
                //wifi模块发布版本号
                String wifi_version = jsonObject.getString(GyroLaserConstant.YUGONG_SOFTWARE_VERSION);
            }
            if (jsonObject.has(GyroLaserConstant.VENDOR_FIRMWARE_VERSION)) {
                //底盘固件版本号
                String firmware_version = jsonObject.getString(GyroLaserConstant.VENDOR_FIRMWARE_VERSION);
                LogUtils.i("-----222  eeeeee >  " + firmware_version);
                robot.getFirmwareInfo().setCompileVerions(firmware_version);
            }
            if (jsonObject.has(GyroLaserConstant.WIFI_SSID)) {
                //WIFI名称
                String wifi_ssid = jsonObject.getString(GyroLaserConstant.WIFI_SSID);
                robot.getFirmwareInfo().setSsid(wifi_ssid);
            }
            if (jsonObject.has(GyroLaserConstant.LOCAL_IP)) {
                //IP
                String local_ip = jsonObject.getString(GyroLaserConstant.LOCAL_IP);
                robot.getFirmwareInfo().setIp(local_ip);
            }
            if (jsonObject.has(GyroLaserConstant.CHASSIS_SN)) {
                //SN
                String chassis_sn = jsonObject.getString(GyroLaserConstant.CHASSIS_SN);
                LogUtils.i("SN===== chassis_sn : " + chassis_sn);
                robot.getFirmwareInfo().setSn(chassis_sn);
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    protected static void parseState(String state, Robot robot) {
        LogUtils.i("N5 robot_state =state=====" + state);
        RobotStatus status = robot.getRobotStatus();
        status.setSubState(RobotStatus.SUBSTATE_NONE);
        if ("Hibernating".equals(state)) {
            //休眠
            status.setWorkState(RobotStatus.STATE_DORMANT);
        } else if ("Standby".equals(state)) {
            //待机
            status.setWorkState(RobotStatus.STATE_STANDBY);
        } else if ("AutoClean".equals(state) || "Cleaning".equals(state)
                || "ZmodeClean".equals(state)) {
            //清扫
            status.setWorkState(RobotStatus.STATE_WORKING);
            status.setWorkMode(RobotStatus.MODE_AUTO_CLEAN);
        } else if ("RoomClean".equals(state)) {
            //选区清扫
            status.setWorkState(RobotStatus.STATE_WORKING);
            status.setWorkMode(RobotStatus.MODE_ROOM_CLEAN);
        } else if ("SpotClean".equals(state)) {
            //局部清扫
            status.setWorkState(RobotStatus.STATE_WORKING);
            status.setWorkMode(RobotStatus.MODE_SPOT_CLEAN);
        } else if ("EdgeClean".equals(state)) {
            //沿墙清扫
            status.setWorkState(RobotStatus.STATE_WORKING);
            status.setWorkMode(RobotStatus.MODE_EDGE_CLEAN);
        } else if ("BackCharging".equals(state)) {
            //回充中
            status.setWorkState(RobotStatus.STATE_WORKING);
            status.setWorkMode(RobotStatus.MODE_RECHARGE);
        } else if ("PauseClean".equals(state) || "PauseBackCharge".equals(state)) {
            //暂停
            status.setWorkState(RobotStatus.STATE_PAUSE);
        } else if ("Malfunction".equals(state)) {
            //故障
            status.setWorkState(RobotStatus.STATE_ERROR);
        } else if ("ChargeDone".equals(state) || "DirCharging".equals(state) || "PileCharging".equals(state)) {
            //充电中
            status.setWorkState(RobotStatus.STATE_CHARGING);
        } else if ("DirectionControl".equals(state)) {
            // 遥控模式 状态限制】同工作中
            status.setWorkState(RobotStatus.STATE_WORKING);
            status.setWorkMode(RobotStatus.MODE_CONTROL);
        }
        LogUtils.d("aaaaaaaaaa 状态-- 发送-- MSG_ROBOT_STATE: ");
        Event.newBuilder().type(Event.MSG_ROBOT_STATE).send();
    }


    @Override
    public void startSweep(com.iot.sweeper.param.CleanParam param) {
        //根据类型判断是什么模式的开始清扫
        int cleanType = param.getType();
        if (cleanType == RobotStatus.MODE_AUTO_CLEAN) {
            //全局清扫
            sendToDevice("working_status", "AutoClean");
            sendToDevice(GyroLaserConstant.WORKING_STATUS, "AutoClean");
        } else if (cleanType == RobotStatus.MODE_EDGE_CLEAN) {
            //沿墙
            sendToDevice(GyroLaserConstant.WORKING_STATUS, "EdgeClean");
        } else if (cleanType == RobotStatus.MODE_SPOT_CLEAN) {
            //局部清扫
            sendToDevice(GyroLaserConstant.WORKING_STATUS, "SpotClean");
        }
    }

    @Override
    public void continueSweep(com.iot.sweeper.param.CleanParam param) {
        sendToDevice(GyroLaserConstant.WORKING_STATUS, "Continue");
    }

    @Override
    public void pauseSweep() {
        sendToDevice(GyroLaserConstant.WORKING_STATUS, "PauseClean");
    }

    @Override
    public void stopSweep() {
        sendToDevice(GyroLaserConstant.WORKING_STATUS, "Standby");
    }

    @Override
    public void startRecharge() {
        sendToDevice(GyroLaserConstant.WORKING_STATUS, "BackCharging");
    }

    @Override
    public void pauseRecharge() {
        sendToDevice(GyroLaserConstant.WORKING_STATUS, "PauseBackCharge");
    }

    @Override
    public void continueRecharge() {
        sendToDevice(GyroLaserConstant.WORKING_STATUS, "Continue");
    }

    @Override
    public void stopRecharge() {
        sendToDevice(GyroLaserConstant.WORKING_STATUS, "Standby");
    }

    @Override
    public void sendAliveHeartbeat() {
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("opt", YuGongConstants.OPT_DEVICE_CONTROL);
            jsonObject.put("thing_name", getDeviceId());
            jsonObject.put("notify_info", "update_map");
            jsonObject.put("timestamp_ms", StringUtils.dateToStamp());
            YuGongSdk.get().sendCmd(jsonObject);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    //强制开关勿扰
    public void forceSwitchDisturbed(boolean isOpen) {
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("opt", YuGongConstants.OPT_DEVICE_CONTROL_ORDER);
            jsonObject.put("thing_name", getDeviceId());
            jsonObject.put("sub_type", getProductId());
            JSONObject jsonOrder = new JSONObject();
            if (isOpen) {
                jsonOrder.put("undisturb_mode", "on");
            } else {
                jsonOrder.put("undisturb_mode", "off");
            }
            jsonObject.put("topic_payload", jsonOrder);
            YuGongSdk.get().sendCmd(jsonObject);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void sendUpgradeUrlToDevice(DataBag dataBag) {
        String notify_info = "";
        String file_name = dataBag.getFile_name();
        if ("chassis".equals(file_name)) {
            notify_info = "chassis_upgrade";//MCU升级
            YuGongPayloadGyroSendMcuUpgradeUrl payload = YuGongPayloadGyroSendMcuUpgradeUrl
                    .newBuilder(YuGongConstants.OPT_DEVICE_CONTROL)
                    .thing_name(getDeviceId())
                    .notify_info(notify_info)
                    .firmware_version(dataBag.getVersion())
                    .chassis_url(dataBag.getUrl())
                    .build();
            LogUtils.i(" MCU 发消息给设备 数据   :" + gson.toJson(payload));
            YuGongSdk.get().getWebService().sendUpgradeUrlToMcuDevice(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataCommon>>() {
                @Override
                public void onResponse(Call<YuGongResponse<YuGongRespDataCommon>> call, retrofit2.Response<YuGongResponse<YuGongRespDataCommon>> response) {
                    YuGongResponse<YuGongRespDataCommon> result = response.body();
                    LogUtils.i("发消息给设备 数据 :" + gson.toJson(result));
                    if (result == null) {
                        String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                        Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                        return;
                    }
                    if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                        YuGongRespDataCommon data = result.getData();
                        //TODO 解析数据
                        Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(true).content(data).send();
                    } else {
                        String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                        Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                    }
                }

                @Override
                public void onFailure(Call<YuGongResponse<YuGongRespDataCommon>> call, Throwable t) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                }
            });
        } else if ("device".equals(file_name)) {
            notify_info = "device_upgrade";//WIFI模块升级
            YuGongPayloadGyroSendWifiUpgradeUrl payload = YuGongPayloadGyroSendWifiUpgradeUrl
                    .newBuilder(YuGongConstants.OPT_DEVICE_CONTROL)
                    .thing_name(getDeviceId())
                    .notify_info(notify_info)
                    .firmware_version(dataBag.getVersion())
                    .device_url(dataBag.getUrl())
                    .build();
            LogUtils.i(" WIFI 发消息给设备 数据   :" + gson.toJson(payload));
            YuGongSdk.get().getWebService().sendUpgradeUrlToWifiDevice(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataCommon>>() {
                @Override
                public void onResponse(Call<YuGongResponse<YuGongRespDataCommon>> call, retrofit2.Response<YuGongResponse<YuGongRespDataCommon>> response) {
                    YuGongResponse<YuGongRespDataCommon> result = response.body();
                    LogUtils.i("发消息给设备 数据 :" + gson.toJson(result));
                    if (result == null) {
                        String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                        Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                        return;
                    }
                    if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                        YuGongRespDataCommon data = result.getData();
                        //TODO 解析数据
                        Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(true).content(data).send();
                    } else {
                        String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                        Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                    }
                }

                @Override
                public void onFailure(Call<YuGongResponse<YuGongRespDataCommon>> call, Throwable t) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                }
            });
        }

    }

    @Override
    public void sendVoiceBagUrlToDevice(DataBag dataBag) {
        YuGongPayloadSendVoiceBagUrl payload = YuGongPayloadSendVoiceBagUrl
                .newBuilder(YuGongConstants.OPT_DEVICE_CONTROL)
                .thing_name(getDeviceId())
                .dataBag(dataBag)
                .build();
        LogUtils.i("  发消息给设备 数据   :" + gson.toJson(payload));
        YuGongSdk.get().getWebService().sendVoiceBagUrlToDevice(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataCommon>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespDataCommon>> call, retrofit2.Response<YuGongResponse<YuGongRespDataCommon>> response) {
                YuGongResponse<YuGongRespDataCommon> result = response.body();
                LogUtils.i("发消息给设备 数据 :" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    YuGongRespDataCommon data = result.getData();
                    //TODO 解析数据
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(true).content(data).send();
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespDataCommon>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    /**
     * 说明 ：| 字段名称 | 数据类型 | 必须 | 字段描述 |
     * | --- | --- | --- | --- |
     * | data_type | String | 是 | 获取数据的类型 |
     * | thing_name | String | 是 | 获取数据的指定设备名称 |
     * | mac | String | 是 | 获取数据的指定设备mac地址 （格式：中间是 -（破折号），不是：（冒号），字母全部转小写） |
     * | resource_list | List | 是 | 所有文件夹列表 |
     * | file_name | String | 是 | 文件夹名 |
     * | describe_file | Dict | 是 | 对应文件夹中描述文件所有内容 |
     */
    public void getDataList(DataParam param) {
        YuGongPayloadDataList payload = YuGongPayloadDataList
                .newBuilder(YuGongConstants.OPT_RESOURCE_LIST_GET)
                .thing_name(getDeviceId())
                .data_type(param.getData_type())
                .mac(StringUtils.stringReplace(getFirmwareInfo().getMac().toLowerCase()))
                .build();
        LogUtils.i("  N5 数据列表 ww  :" + gson.toJson(payload));
        YuGongSdk.get().getWebService().getDataList(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataList>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespDataList>> call, retrofit2.Response<YuGongResponse<YuGongRespDataList>> response) {
                YuGongResponse<YuGongRespDataList> result = response.body();
                LogUtils.i("N5 数据列表 :" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_VOICE_LIST).result(false).content(errorInfo).send();
                    return;
                }

                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    YuGongRespDataList data = result.getData();
                    if (param.getData_type().equals("voice_package")) {
                        Event.newBuilder().type(Event.MESSAGE_TYPE_VOICE_LIST).result(true).content(data).send();
                    } else if (param.getData_type().equals("clean_record")) {
                        List<CleanRecord> recordList = new ArrayList<>();
                        recordList.clear();
                        List<YuGongRespDataList.ResourceListBean> resource_list = data.getResource_list();
                        for (int i = resource_list.size() - 1; i >= 0; i--) {
                            YuGongRespDataList.ResourceListBean resourceListBean = resource_list.get(i);
                            String[] fileName = resourceListBean.getFile_name().split("_");
                            String date = fileName[1].substring(0, 4) + "-" + fileName[1].substring(4, 6) + "-" + fileName[1].substring(6, 8);
                            String time = fileName[2].substring(0, 2) + ":" + fileName[2].substring(2, 4) + ":" + fileName[2].substring(4, 6);
                            String startTime = date + "  " + time;
                            int cleanTime = Integer.valueOf(fileName[3]);
                            float cleanArea = Float.valueOf(fileName[4]);
                            CleanRecord cleanRecordAdapterBean = new CleanRecord();
                            cleanRecordAdapterBean.setStartTime(startTime);
                            cleanRecordAdapterBean.setCleanTime(cleanTime);
                            cleanRecordAdapterBean.setArea((int) cleanArea);
                            cleanRecordAdapterBean.setIsDoneNormal(1);
                            cleanRecordAdapterBean.setFileName(resourceListBean.getFile_name());
                            recordList.add(cleanRecordAdapterBean);
                        }
                        //getRecordMapDetail(recordList);
                        Event.newBuilder().type(Event.MESSAGE_TYPE_GET_CLEAN_RECORD).result(true).content(recordList).send();
                    } else if (param.getData_type().equals("upgrade_package")) {
                        List<YuGongRespDataList.ResourceListBean> resource_list = data.getResource_list();
                        LogUtils.i("upgrade_package " + new Gson().toJson(resource_list));
                        if (resource_list.size() == 0) {
                            Event.newBuilder().type(Event.MESSAGE_TYPE_CHECK_NEW_VERSION).result(false).content("upgrade data is null").send();
                            return;
                        }
                        String file_name;
                        FirmwareUpdateInfo firmwareUpdateInfo = new FirmwareUpdateInfo();
                        for (int i = 0; i < resource_list.size(); i++) {
                            file_name = resource_list.get(i).getFile_name();
                            YuGongRespDataList.ResourceListBean resourceListBean = resource_list.get(i);
                            //“notify”表示提醒升级，”detect”表示检测升级， “force”表示强制升级，”silent”表示静默升级
                            String push_type = resourceListBean.getPush_type();
                            LogUtils.i("固件升级的状态 ： " + push_type);

                            String describeFile = resourceListBean.getDescribe_file();
                            try {
                                JSONObject jsonObject = new JSONObject(describeFile);
                                String type = jsonObject.getString("type");
                                LogUtils.i("upgrade_package type : " + type);
                                if ("chassis".equals(type)) {
                                    String version = jsonObject.getString("version");
                                    JSONObject conditions = jsonObject.getJSONObject("conditions");
                                    String cur_vendor_firmware_version = conditions.getString("cur_vendor_firmware_version");
                                    if (!version.equals(cur_vendor_firmware_version)) {
                                        //版本不一样 有升级
                                        LogUtils.i("upgrade_package 版本不一样  : " + currentDevice.getFirmwareUpdateInfo().getState());
                                        firmwareUpdateInfo.setUpgradeStatus(1);
                                        firmwareUpdateInfo.setNewVersion(version);
                                        firmwareUpdateInfo.setCurrentVersion(cur_vendor_firmware_version);
                                    } else {
                                        firmwareUpdateInfo.setUpgradeStatus(0);
                                        firmwareUpdateInfo.setNewVersion(version);
                                        firmwareUpdateInfo.setCurrentVersion(version);
                                    }
                                    JSONArray upgrade_info = jsonObject.getJSONArray("upgrade_info");
                                    for (int j = 0; j < upgrade_info.length(); j++) {
                                        String desc = upgrade_info.get(j).toString();
                                        JSONObject desc_json = new JSONObject(desc);
                                        if (desc_json.has("cn")) {
                                            String cn = desc_json.getString("cn");
                                            firmwareUpdateInfo.setDesc(cn);
                                        }
                                        if (desc_json.has("en")) {
                                            String en = desc_json.getString("en");
                                            firmwareUpdateInfo.setDesc_en(en);
                                        }
                                        LogUtils.i("upgrade_package string  : " + desc);
                                    }

                                } else if ("device".equals(type)) {
                                    //WIFI模块
                                    String version = jsonObject.getString("version");
                                    JSONObject conditions = jsonObject.getJSONObject("conditions");
                                    String cur_yugong_softmware_version = conditions.getString("cur_yugong_softmware_version");
                                    if (!version.equals(cur_yugong_softmware_version)) {
                                        firmwareUpdateInfo.setUpgradeStatus(1);
                                        firmwareUpdateInfo.setNewVersion(version);
                                        firmwareUpdateInfo.setCurrentVersion(cur_yugong_softmware_version);
                                    } else {
                                        firmwareUpdateInfo.setUpgradeStatus(0);
                                        firmwareUpdateInfo.setNewVersion(version);
                                        firmwareUpdateInfo.setCurrentVersion(version);
                                    }
                                    JSONArray upgrade_info = jsonObject.getJSONArray("upgrade_info");
                                    for (int j = 0; j < upgrade_info.length(); j++) {
                                        String desc = upgrade_info.get(j).toString();
                                        JSONObject desc_json = new JSONObject(desc);
                                        if (desc_json.has("cn")) {
                                            String cn = desc_json.getString("cn");
                                            firmwareUpdateInfo.setDesc(cn);
                                        }
                                        if (desc_json.has("en")) {
                                            String en = desc_json.getString("en");
                                            firmwareUpdateInfo.setDesc_en(en);
                                        }
                                        LogUtils.i("upgrade_package string  : " + desc);
                                    }
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                            firmwareUpdateInfo.setFileName(file_name);
                            Event.newBuilder().type(Event.MESSAGE_TYPE_CHECK_NEW_VERSION).result(true).content(firmwareUpdateInfo).send();
                        }
                    }
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    Event.newBuilder().type(Event.MESSAGE_TYPE_VOICE_LIST).result(false).content(errorInfo).send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespDataList>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                LogUtils.i("数据列表 失败 :" + errorInfo);
            }
        });
    }

    public void getData(DataParam param) {
        //chassis_upgrade:升级底盘固件 device_upgrade:升级wifi模块固件
        YuGongPayloadData payload = YuGongPayloadData
                .newBuilder(YuGongConstants.OPT_RESOURCE_DATA_GET)
                .thing_name(getDeviceId())
                .data_type(param.getData_type())
                .file_name(param.getFile_name())
                .mac(StringUtils.stringReplace(getFirmwareInfo().getMac().toLowerCase()))
                .build();
        LogUtils.i("  : 获取数据 nn   :" + gson.toJson(payload));
        YuGongSdk.get().getWebService().getData(payload).enqueue(new Callback<YuGongResponse<YuGongRespData>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespData>> call, retrofit2.Response<YuGongResponse<YuGongRespData>> response) {
                YuGongResponse<YuGongRespData> result = response.body();
                LogUtils.i("获取数据 :" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    YuGongRespData data = result.getData();
                    if (param.getData_type().equals("voice_package")) {
                        Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(true).content(data).send();
                    } else if (param.getData_type().equals("clean_record")) {
                        List<YuGongRespData.FileListBean> listBeans = data.getFile_list();
                        List<CleanRecord> cleanRecords = new ArrayList<>();
                        CleanRecord cleanRecord = new CleanRecord();
                        cleanRecord.setUrl(listBeans.get(0).getData_s3_url());
                        cleanRecords.add(cleanRecord);
                        GetCloudFileRunnable getCloudFileRunnable = new GetCloudFileRunnable(cleanRecords, Event.MESSAGE_TYPE_GET_CLEAN_RECORD_DETAIL);
                        threadPoolExecutor.execute(getCloudFileRunnable);
                    } else if (param.getData_type().equals("upgrade_package")) {
                        Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_UPGRADE_URL_TO_DEVICE).result(true).content(data).send();
                    }
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespData>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    public void getRecordMapDetail(List<CleanRecord> multiMapDetails) {
        GetRecordMapDetailList getRecordMapDetailList = new GetRecordMapDetailList(multiMapDetails);
        getRecordMapDetailList.start();
    }


    private class GetRecordMapDetailList extends Thread {
        List<CleanRecord> multiMapDetails;
        OkHttpClient okHttpClient;

        public GetRecordMapDetailList(List<CleanRecord> multiMapDetails) {
            this.multiMapDetails = multiMapDetails;
            okHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(20, TimeUnit.SECONDS)
                    .build();
        }

        @Override
        public void run() {
            super.run();
            CountDownLatch countDownLatch = new CountDownLatch(multiMapDetails.size());
            for (int i = 0; i < multiMapDetails.size(); i++) {
                CleanRecord cleanRecord = multiMapDetails.get(i);
                YuGongPayloadData payload = YuGongPayloadData
                        .newBuilder(YuGongConstants.OPT_RESOURCE_DATA_GET)
                        .thing_name(getDeviceId())
                        .data_type("clean_record")
                        .file_name(cleanRecord.getFileName())
                        .mac(StringUtils.stringReplace(getFirmwareInfo().getMac().toLowerCase()))
                        .build();
                LogUtils.i("  : 获取数据 nn   :" + gson.toJson(payload));
                YuGongSdk.get().getWebService().getData(payload).enqueue(new Callback<YuGongResponse<YuGongRespData>>() {
                    @Override
                    public void onResponse(Call<YuGongResponse<YuGongRespData>> call, retrofit2.Response<YuGongResponse<YuGongRespData>> response) {
                        YuGongResponse<YuGongRespData> result = response.body();
                        LogUtils.i("获取数据 :" + gson.toJson(result));
                        if (result == null) {
                            String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                            Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                            return;
                        }
                        if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                            YuGongRespData data = result.getData();
                            List<YuGongRespData.FileListBean> listBeans = data.getFile_list();
                            for (YuGongRespData.FileListBean listBean : listBeans) {
                                cleanRecord.setUrl(listBean.getData_s3_url());
                            }
                        } else {
                            String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                            Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                        }

                        countDownLatch.countDown();
                    }

                    @Override
                    public void onFailure(Call<YuGongResponse<YuGongRespData>> call, Throwable t) {
                        String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                        countDownLatch.countDown();
                    }
                });
            }
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            for (int i = 0; i < multiMapDetails.size(); i++) {
                CleanRecord cleanRecord = multiMapDetails.get(i);
                if (cleanRecord.getUrl() != null) {
                    try {
                        Request request = new Request.Builder().url(cleanRecord.getUrl()).get().build();
                        okhttp3.Call call1 = okHttpClient.newCall(request);
                        byte[] data = call1.execute().body().bytes();
                        LogUtils.ls("pathUrl ---response  : " + data);
                        GyroMapDataParser.parseRecord(cleanRecord, data);
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    }
                }
            }
            Event.newBuilder().type(Event.MESSAGE_TYPE_GET_CLEAN_RECORD).result(true).content(multiMapDetails).send();
        }
    }

    /**
     * 通过连接获取云存储文件内容
     */
    private class GetCloudFileRunnable extends Thread {
        List<CleanRecord> multiMapDetails;
        OkHttpClient okHttpClient;
        int eventValue;

        public GetCloudFileRunnable(List<CleanRecord> multiMapDetails, int eventValue) {
            this.multiMapDetails = multiMapDetails;
            this.eventValue = eventValue;
            okHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(20, TimeUnit.SECONDS)
                    .build();
        }

        @Override
        public void run() {
            super.run();
            for (int i = 0; i < multiMapDetails.size(); i++) {
                CleanRecord cleanRecord = multiMapDetails.get(i);
                if (cleanRecord.getUrl() != null) {
                    try {
                        Request request = new Request.Builder().url(cleanRecord.getUrl()).get().build();
                        okhttp3.Call call1 = okHttpClient.newCall(request);
                        byte[] data = call1.execute().body().bytes();
                        LogUtils.ls("pathUrl ---response  : " + data);
                        GyroMapDataParser.parseRecord(cleanRecord, data);
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    }
                }
            }
            Event.newBuilder().type(eventValue).result(true).content(multiMapDetails).send();
        }
    }

    @Override
    public void getCleanRecord(GetCleanRecordParam param) {
        DataParam dataParam = new DataParam();
        dataParam.setData_type("clean_record");
        getDataList(dataParam);
    }

    @Override
    public void getCleanRecordDetail(GetCleanRecordDetailParam param) {
        /*//陀螺仪查询列表时已经将地图数据下载了
        List<CleanRecord> records = new ArrayList<>();
        records.add(param.getCleanRecord());
        Event.newBuilder().type(Event.MESSAGE_TYPE_GET_CLEAN_RECORD_DETAIL).result(true).content(records).send();*/

        DataParam dataParam = new DataParam();
        dataParam.setData_type("clean_record");
        dataParam.setFile_name(param.getCleanRecord().getFileName());
        getData(dataParam);
    }

    @Override
    public void sendTimeZoneToDevice() {

    }

    @Override
    public void setDeviceCleanSettings(CleanSettingParam param) {
        LogUtils.i("setCleanSettings ---------------------------N5 ");
        //吸力
        if (param.hasset_suction) {
            String fanString = YuGongDataConverter.getSuctionString(param.getSuction());
            YuGongChannelReqSuction payload = YuGongChannelReqSuction
                    .newBuilder()
                    .sub_type(currentDevice.getProductId())
                    .thing_name(currentDevice.getDeviceId())
                    .fan_status(fanString)
                    .build();
            LogUtils.i("N5 吸力 : " + new Gson().toJson(payload));
            YuGongSdk.get().sendCmd(payload);
            setIgnoreStateCount();
        }

        //断点续扫
        if (param.hasset_breakpointResume) {
            YuGongChannelReqBreakContinue payload = YuGongChannelReqBreakContinue
                    .newBuilder()
                    .sub_type(currentDevice.getProductId())
                    .thing_name(currentDevice.getDeviceId())
                    .continue_clean(param.isBreakpointResume())
                    .build();
            LogUtils.i("N5 断点续扫 : " + new Gson().toJson(payload));
            YuGongSdk.get().sendCmd(payload);
            setIgnoreStateCount();
        }
        //灯光
        if (param.hasset_lightSwitch) {
            setLightControls(param.getLightSwitch());
        }
    }

    @Override
    public void setLightControls(boolean lightSwitch) {
        YuGongChannelReqLight payload = YuGongChannelReqLight
                .newBuilder()
                .sub_type(currentDevice.getProductId())
                .thing_name(currentDevice.getDeviceId())
                .light(lightSwitch)
                .build();
        YuGongSdk.get().sendCmd(payload);
        setIgnoreStateCount();
        LogUtils.i("N5 灯光指令下发 ：" + new Gson().toJson(payload));
    }

    public void sendToDevice(String key, Object value) {
        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("opt", YuGongConstants.OPT_DEVICE_CONTROL_ORDER);
            jsonObject.put("thing_name", getDeviceId());
            jsonObject.put("sub_type", getProductId());
            JSONObject jsonOrder = new JSONObject();
            jsonOrder.put(key, value);
            jsonObject.put("topic_payload", jsonOrder);
            YuGongSdk.get().sendCmd(jsonObject);
            LogUtils.i("sendToDevice : " + jsonObject.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
        AppStatusConstant.ignoreStateCount = 1;

    }

    @Override
    public void getAppointment() {
        YuGongGetAppointmentList payload = new YuGongGetAppointmentList();
        payload.setOpt(YuGongConstants.OPT_GET_APPOINTMENT);
        payload.setThing_name(getDeviceId());

        LogUtils.i("查询预约:" + gson.toJson(payload));
        YuGongSdk.get().getWebService().getAppointmentList(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataGetAppointment>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespDataGetAppointment>> call, retrofit2.Response<YuGongResponse<YuGongRespDataGetAppointment>> response) {
                YuGongResponse<YuGongRespDataGetAppointment> result = response.body();
                LogUtils.i("查询预约: 回复" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    //TODO 解析数据
                    List<Appointment> list = new ArrayList<>();
                    List<YuGongRespDataGetAppointment.AutoListBean> autoListBeans = result.getData().getAuto_list();
                    for (int i = 0; i < autoListBeans.size(); i++) {
                        Appointment appointment = new Appointment();
                        YuGongRespDataGetAppointment.AutoListBean autoListBean = autoListBeans.get(i);
                        appointment.setRepeat(GyroDataConverter.getRepeat(autoListBean.getWeek_repeat()));
                        appointment.setSwitch(autoListBean.getIs_on());
                        appointment.setAutoId(autoListBean.getAuto_id());
                        String toLocal = StringUtils.UTC2Local(autoListBean.getTimer_hour() + ":" + autoListBean.getTimer_minute());
                        String[] split = toLocal.split(":");
                        appointment.setTime(Integer.valueOf(split[0]) * 3600 + Integer.valueOf(split[1]) * 60);
                        appointment.setEnable(autoListBean.getIs_on());
                        YuGongRespDataGetAppointment.AutoListBean.CmdContentBean cmdContentBean = autoListBean.getCmd_content();
                        if (cmdContentBean.getWorking_status().equals("AutoClean")) {
                            appointment.setCleanMode(0);
                        } else if (cmdContentBean.getWorking_status().equals("EdgeClean")) {
                            appointment.setCleanMode(1);
                        } else if (cmdContentBean.getWorking_status().equals("SpotClean")) {
                            appointment.setCleanMode(2);
                        }

                        CleanParam cleanParam = new CleanParam();
                        if (cmdContentBean.getFan_status().equals("Quiet")) {
                            cleanParam.suction = 1;
                        } else if (cmdContentBean.getFan_status().equals("Normal")) {
                            cleanParam.suction = 2;
                        } else if (cmdContentBean.getFan_status().equals("Strong")) {
                            cleanParam.suction = 3;
                        } else if (cmdContentBean.getFan_status().equals("Max")) {
                            cleanParam.suction = 4;
                        }
                        appointment.setCleanParam(cleanParam);
                        list.add(appointment);

                    }
                    Event.newBuilder().type(Event.MESSAGE_TYPE_QUERY_ALARM).result(true).content(list).send();
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    LogUtils.i("查询预约:" + gson.toJson(errorInfo));
                    Event.newBuilder().type(Event.MESSAGE_TYPE_QUERY_ALARM).result(false).content("query").send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespDataGetAppointment>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    @Override
    public void addAppointment(AddAppointmentParam param) {
        YuGongGyroAddAppointment payload = GyroDataConverter.getAddAppointmentPayload(param.getAppointment());
        payload.setObject_id(getDeviceId());
        LogUtils.i("  添加预约:" + gson.toJson(payload));
        YuGongSdk.get().getWebService().addAppointment(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataCommon>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespDataCommon>> call, retrofit2.Response<YuGongResponse<YuGongRespDataCommon>> response) {
                YuGongResponse<YuGongRespDataCommon> result = response.body();
                LogUtils.i("添加预约: 回复" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    //TODO 解析数据
                    Event.newBuilder().type(Event.MESSAGE_TYPE_QUERY_ALARM).result(true).content("add").send();
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    LogUtils.i("添加预约:" + gson.toJson(errorInfo));
                    Event.newBuilder().type(Event.MESSAGE_TYPE_QUERY_ALARM).result(false).content("add").send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespDataCommon>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    @Override
    public void changeAppointment(ChangeAppointmentParam param) {
        YuGongGyroModifyAppointment payload = GyroDataConverter.getModifyAppointmentPayload(param.getAppointment());
        payload.setObject_id(getDeviceId());
        LogUtils.i("修改预约:" + gson.toJson(payload));
        YuGongSdk.get().getWebService().modifyAppointment(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataCommon>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespDataCommon>> call, retrofit2.Response<YuGongResponse<YuGongRespDataCommon>> response) {
                YuGongResponse<YuGongRespDataCommon> result = response.body();
                LogUtils.i("修改预约: 回复" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    //TODO 解析数据
                    Event.newBuilder().type(Event.MESSAGE_TYPE_QUERY_ALARM).result(true).content("change").send();
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    LogUtils.i("修改预约:" + gson.toJson(errorInfo));
                    Event.newBuilder().type(Event.MESSAGE_TYPE_QUERY_ALARM).result(false).content("change").send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespDataCommon>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    @Override
    public void switchAppointment(ChangeAppointmentParam param) {
        YuGongPayloadSwitchAppointment payload = YuGongPayloadSwitchAppointment
                .newBuilder()
                .auto_id(param.getAppointment().getAutoId())
                .is_on(param.getAppointment().isEnable())
                .build();

        LogUtils.i("预约开关:" + gson.toJson(payload));
        YuGongSdk.get().getWebService().switchAppointment(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataCommon>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespDataCommon>> call, retrofit2.Response<YuGongResponse<YuGongRespDataCommon>> response) {
                YuGongResponse<YuGongRespDataCommon> result = response.body();
                LogUtils.i("预约开关: 回复" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_MODIFY_APPOINTMENT).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    //TODO 解析数据
                    Event.newBuilder().type(Event.MESSAGE_TYPE_MODIFY_APPOINTMENT).result(true).content("switch").send();
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    LogUtils.i("预约开关:" + gson.toJson(errorInfo));
                    Event.newBuilder().type(Event.MESSAGE_TYPE_MODIFY_APPOINTMENT).result(false).content("switch").send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespDataCommon>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    @Override
    public void deleteAppointment(DeleteAppointmentParam param) {
        YuGongPayloadDeleteAppointment payload = YuGongPayloadDeleteAppointment
                .newBuilder().auto_id(param.getAppointment().getAutoId()).build();
        LogUtils.i("删除预约:" + gson.toJson(payload));
        YuGongSdk.get().getWebService().deleteAppointment(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataCommon>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespDataCommon>> call, retrofit2.Response<YuGongResponse<YuGongRespDataCommon>> response) {
                YuGongResponse<YuGongRespDataCommon> result = response.body();
                LogUtils.i("删除预约: 回复" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_MODIFY_APPOINTMENT).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    //TODO 解析数据
                    Event.newBuilder().type(Event.MESSAGE_TYPE_MODIFY_APPOINTMENT).result(true).content("delete").send();
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    LogUtils.i("删除预约:" + gson.toJson(errorInfo));
                    Event.newBuilder().type(Event.MESSAGE_TYPE_MODIFY_APPOINTMENT).result(false).content("delete").send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespDataCommon>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    /**
     * 查询勿扰开关、时间
     */
    @Override
    public void getQuiteTimeSettings() {
        YuGongSdk.get().getNoDisturb(this);
    }

    @Override
    public void getCleanRecordStatistics() {
        YuGongSdk.get().getCleanStatistic(this);
    }

    /**
     * 设置勿扰模式开关、时间
     */
    @Override
    public void setQuiteTimeSettings(SetQuiteTimeParam param) {
        if (param.ismSwitch()) {
            if (param.isHasDisturbed()) {
                if (param.hasSetSwitch()) {
                    //设置勿扰模式开关
                    YuGongSdk.get().switchNoDisturb(param.ismSwitch(), param.getUndisturbedId());
                    if (param.ismSwitch()) {
                        Calendar calendar = Calendar.getInstance(); // 获取当前时间的Calendar实例
                        int hour = calendar.get(Calendar.HOUR_OF_DAY); // 获取当前小时
                        int minute = calendar.get(Calendar.MINUTE); // 获取当前分钟
                        LogUtils.i("force switch disturbed hour is " + hour + " minute is " + minute + "=====" + param.getStartHour() + ":" + param.getStartMin());
                        if ((param.getStartHour() * 3600 + param.getStartMin() * 60) <= (hour * 3600 + minute * 60)) {
                            LogUtils.i("force switch disturbed true");
                            forceSwitchDisturbed(true);
                        }
                    }
                }
                if (param.hasSetTime()) {
                    //修改勿扰
                    YuGongPayloadModifyNoDisturb payload1 = GyroDataConverter.getModifyNoDisturbPayload(param, this);
                    YuGongSdk.get().modifyNoDisturb(payload1);
                }
            } else {
                //添加勿扰
                YuGongPayloadAddNoDisturb payload = GyroDataConverter.getAddNoDisturbPayload(param, this);
                YuGongSdk.get().addNoDisturb(payload);
            }
        } else {
            //设置勿扰模式开关
            YuGongSdk.get().switchNoDisturb(param.ismSwitch(), param.getUndisturbedId());
            LogUtils.i("force switch disturbed false");
            forceSwitchDisturbed(false);
        }
    }

    @Override
    public void remoteControl(RemoteControlParam param) {
        RemoteControlParam.Movement moveDirection = param.getMotion();
        String instruct = "0";
        if (moveDirection == RemoteControlParam.Movement.LEFT) {
            instruct = "move_left";
        } else if (moveDirection == RemoteControlParam.Movement.RIGHT) {
            instruct = "move_right";
        } else if (moveDirection == RemoteControlParam.Movement.FORWORD) {
            instruct = "move_front";
        } else if (moveDirection == RemoteControlParam.Movement.BACKWORD) {
            instruct = "move_back";
        } else if (moveDirection == RemoteControlParam.Movement.STOP) {
            instruct = "move_stop";
        }
        YuGongChannelReqRemoteControl payload = YuGongChannelReqRemoteControl
                .newBuilder()
                .sub_type(currentDevice.getProductId())
                .thing_name(currentDevice.getDeviceId())
                .notify_info("direction_control")
                .command(instruct)
                .timestamp_ms(StringUtils.dateToStamp())
                .build();
        LogUtils.i("send remoteControl data ：" + new Gson().toJson(payload));
        YuGongSdk.get().sendCmd(payload);
    }

    @Override
    public void stopRemoteControl() {
        YuGongChannelReqWorkingStatus payload = YuGongChannelReqWorkingStatus
                .newBuilder()
                .sub_type(currentDevice.getProductId())
                .thing_name(currentDevice.getDeviceId())
                .workingStatus("move_stop")
                .ts(StringUtils.dateToStamp())
                .build();
        LogUtils.i("send stopRemoteControl data ：" + new Gson().toJson(payload));
        YuGongSdk.get().sendCmd(payload);
    }

    @Override
    public void resetComsuptionInfo(ResetComsuptionParam param) {
        String reset = param.getReset();
        String dp = "";
        //自动清扫
        if (reset.equals("resetFilter")) {
            //滤网
            dp = "reset_filter";
        } else if (reset.equals("resetSidebrush")) {
            //边刷
            dp = "reset_side_brush";
        }
        YuGongSdk.get().setResetComsuptionInfo(currentDevice, dp);
    }

    @Override
    public void locateDevice() {
        YuGongChannelReqLocateDevice payload = YuGongChannelReqLocateDevice
                .newBuilder()
                .sub_type(currentDevice.getProductId())
                .thing_name(currentDevice.getDeviceId())
                .notify_info("find_robot")
                .build();
        LogUtils.i("N5 定位机器人： " + new Gson().toJson(payload));
        YuGongSdk.get().sendCmd(payload);
    }

    @Override
    public void removeMultiMapList(RemoveMultiMapList param) {

    }

    @Override
    public void uploadLog() {
        //这个是使用dp上传的，陀螺仪目前不支持
    }

    @Override
    public String getFaultMsgByCode(Context context, String faltCode) {
        int srrCode = Integer.parseInt(faltCode);
//        int errCode = getFaultCode(srrCode - 1);
        String errType = "";
        String errDetail = "";
        switch (srrCode) {
            case 1:
                errType = context.getString(R.string.U_Err_Gyro_1);
                break;
            case 2:
                errType = context.getString(R.string.U_Err_Gyro_2);
                break;
            case 3:
                errType = context.getString(R.string.U_Err_Gyro_3);
                break;
            case 4:
                errType = context.getString(R.string.U_Err_Gyro_4);
                break;
            case 5:
                errType = context.getString(R.string.U_Err_Gyro_5);
                break;
            case 6:
                errType = context.getString(R.string.U_Err_Gyro_6);
                break;
            case 7:
                errType = context.getString(R.string.U_Err_Gyro_7);
                break;
            case 8:
                errType = context.getString(R.string.U_Err_Gyro_8);
                break;
            case 9:
                errType = context.getString(R.string.U_Err_Gyro_9);
                break;
            case 10:
                errType = context.getString(R.string.U_Err_Gyro_10);
                break;
            case 11:
                //errType = context.getString(R.string.);
                break;
            case 12:
                errType = context.getString(R.string.U_Err_Gyro_12);
                break;
            case 13:
                errType = context.getString(R.string.U_Err_Gyro_13);
                break;
            default:
                errType = "恢复正常";
                break;
        }
        return errType;
    }

    @Override
    public String getErrorMsgByCode(Context context, String errorCode) {
        Resources res = context.getResources();
        if (YuGongError.ERROR_CODE_NETWORK_ERROR.equals(errorCode)) {
            return res.getString(R.string.U_T_Network_Err);
        } else if (YuGongError.ERROR_CODE_ILLEGAL_USER.equals(errorCode)) {
            return res.getString(R.string.L_T_IllegalUsers);
        } else if (YuGongError.ERROR_CODE_VERIFY_CODE_COUNT_LIMIT.equals(errorCode)) {
            return res.getString(R.string.U_T_Code_TimesLimit);
        } else if (YuGongError.ERROR_CODE_VERIFY_CODE_RATE_LIMIT.equals(errorCode)) {
            return res.getString(R.string.U_T_Code_Frequently);
        } else if (YuGongError.ERROR_CODE_REGISTER_USER_EXIST.equals(errorCode)) {
            return res.getString(R.string.L_T_Register_Un_Existed);
        } else if (YuGongError.ERROR_CODE_USER_NOT_EXIST.equals(errorCode)) {
            return res.getString(R.string.U_T_Un_No);
        } else if (YuGongError.ERROR_CODE_VERIFY_CODE_ERROR.equals(errorCode)) {
            return res.getString(R.string.U_T_Code_No);
        } else if (YuGongError.ERROR_CODE_VERIFY_CODE_EXPIRED.equals(errorCode)) {
            return res.getString(R.string.U_T_Code_Expired);
        } else if (YuGongError.ERROR_CODE_LOGIN_ERROR_PASSWORD.equals(errorCode)) {
            return res.getString(R.string.L_T_Un_Err);
        } else if (YuGongError.ERROR_CODE_SEND_VERIFY_CODE_FAIL.equals(errorCode)) {
            return res.getString(R.string.U_T_Code_No);
        } else {
            return res.getString(R.string.U_UnknownErr);
        }

    }

    protected int getFaultCode(int errCode) {
        //RS01 RS11 GD  LF  不加   其余-1
        int code = 1;
        while (errCode >= 2) {
            errCode = errCode / 2;
            code += 1;
        }
        return code;
    }
}
